package controller;

import java.awt.FileDialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.JOptionPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import modle.File;
import modle.Task;
import modle.TaskFile;
import modle.User;

import view.TaskFrame;
import view.TaskPanel;

import dao.FileDao;
import dao.TaskDao;
import dao.TaskFileDao;

public class TaskController implements ActionListener, ListSelectionListener {

	TaskFrame taskFrame;
	TaskPanel taskPanel;

	public TaskController(TaskPanel taskPanel) {
		// TODO Auto-generated constructor stub
		taskFrame = taskPanel.getTaskFrame();
		this.taskPanel = taskPanel;
	}

	public void actionPerformed(ActionEvent event) {
		// TODO Auto-generated method stub
		if (event.getSource() == taskPanel.getAddTaskButton()) {
			addTask();
		}
		if (event.getSource() == taskPanel.getModifyButton()) {
			modifyTask();
		}
		if (event.getSource() == taskPanel.getRemoveTaskButton()) {
			removerTask();
		}
		if (event.getSource() == taskPanel.getAddFileButton()) {
			addFile();
		}
		if (event.getSource() == taskPanel.getDelFileButton()) {
			delFile();
		}
	}

	private void addFile() {
		FileDialog fileDialog = new FileDialog(taskFrame);
		fileDialog.setVisible(true);
		String fileName = fileDialog.getFile();
		String filePath = fileDialog.getDirectory() + fileName;

		if (fileName == null)
			return;
		if (filePath == null)
			return;
		// whether the file is existent
		FileDao fileDao = new FileDao();
		File file;
		List<File> files = fileDao.findByFilePath(filePath
				.replace("\\", "\\\\"));
		if (files == null || files.isEmpty()) {
			// save the file
			file = new File(fileName, filePath);
			if (fileDao.save(file) == 0) {
				fileDao.closeConnection();
				showMessage("Add File Failed!");
				return;
			}
			// return the fileId
			files = fileDao.findByFilePath(file.getFilePath().replace("\\",
					"\\\\"));
			file = files.get(0);
		} else
			file = files.get(0);

		fileDao.closeConnection();
		// save the taskFile
		int select = taskPanel.getTaskTable().getSelectedRow();
		List<Task> tasks = getUser().getTasks();
		Task task = tasks.get(select);
		TaskFile taskFile = new TaskFile(task, file);
		TaskFileDao taskFileDao = new TaskFileDao();
		if (taskFileDao.save(taskFile) > 0) {
			task.getFiles().add(file);
			taskPanel.getFileTableModel().setData(task.getFiles());
			showMessage("Add File Successfully!");
		} else {
			clearUselessFile();
			showMessage("Add File Failed!");
		}
		taskFileDao.closeConnection();
	}

	private void addTask() {
		Task task = new Task();
		TaskDao taskDao = new TaskDao();
		getTaskFromPanel(task);
		task.setUser(getUser());
		if (taskDao.save(task) > 0) {
			showMessage("Add Task Successfully!");
			task = taskDao.findByTaskName(task.getTaskName()).get(0);
			getUser().getTasks().add(task);
			taskPanel.getTaskTableModel().setData(getUser().getTasks());
			taskPanel.init();
		} else
			showMessage("Add Task Failed!");
		taskDao.closeConnection();
	}

	public void clearUselessFile() {
		FileDao fileDao = new FileDao();
		String sql = " delete from file " + " where not exists( "
				+ " select * from task_file "
				+ " where file.fileId=task_file.fileId); ";
		fileDao.execute(sql);
	}

	private void delFile() {
		int selectTask = taskPanel.getTaskTable().getSelectedRow();
		int selectFile = taskPanel.getFilesTable().getSelectedRow();
		List<Task> tasks = getUser().getTasks();
		Task task = tasks.get(selectTask);
		if (selectTask < 0 || selectTask >= tasks.size())
			return;
		List<File> files = task.getFiles();
		File file = files.get(selectFile);
		if (selectFile < 0 || selectFile >= files.size())
			return;
		FileDao fileDao = new FileDao();
		if (fileDao.delete(file) > 0) {
			task.getFiles().remove(selectFile);
			taskPanel.getFileTableModel().setData(files);
			taskPanel.getDelFileButton().setEnabled(false);
			showMessage("Delete File Successfully!");
		} else {
			showMessage("Delete File Failed!");
		}
		fileDao.closeConnection();
	}

	private void fielTableIsChosen() {
		// TODO Auto-generated method stub
		taskPanel.getDelFileButton().setEnabled(true);
	}

	private void getTaskFromPanel(Task task) {
		if (task == null)
			return;
		task.setTaskName(taskPanel.getTaskNameField().getText());
		task.setDeadline(taskPanel.getDeadlineField().getText());
		task.setPriority(Integer.parseInt(taskPanel.getPriorityComboBox()
				.getSelectedItem().toString()));
		task.setTaskIntroduction(taskPanel.getIntroductionArea().getText());
	}

	public User getUser() {
		return taskFrame.getUser();
	}

	/**
	 * get the files of the task from database
	 * 
	 * @param task
	 */
	@SuppressWarnings("unchecked")
	private void loadTask(Task task) {
		if (task == null)
			return;
		String sql = " select * from file where exists( "
				+ "select * from task_file " + "where task_file.taskid="
				+ task.getTaskId() + " and "
				+ " task_file.fileid=file.fileid) ";
		FileDao fileDao = new FileDao();
		if (fileDao.execute(sql)) {
			task.setFiles(fileDao.getList());
		}
	}

	public void loginSuccessfully() {
		taskPanel.getTaskTableModel().setData(getUser().getTasks());
		taskPanel.getFileTableModel().setData(null);
	}

	private void modifyTask() {
		// TODO Auto-generated method stub
		int select = taskPanel.getTaskTable().getSelectedRow();
		Task task = new Task();
		List<Task> tasks = getUser().getTasks();
		if (select < 0 || select >= tasks.size())
			return;
		task.setTaskId((tasks.get(select)).getTaskId());
		getTaskFromPanel(task);

		TaskDao taskDao = new TaskDao();
		if (taskDao.update(task) > 0) {
			getUser().getTasks().set(select, task);
			showMessage("Modify Successfully!");
		} else
			showMessage("Modify Failed!");

		taskPanel.getTaskTableModel().setData(getUser().getTasks());
		taskDao.closeConnection();
	}

	/**
	 * @return void
	 */
	private void removerTask() {
		int select = taskPanel.getTaskTable().getSelectedRow();
		List<Task> tasks = getUser().getTasks();
		// judge the select is legal or not
		if (select < 0 || select > tasks.size())
			return;
		Task task = tasks.get(select);
		TaskDao taskDao = new TaskDao();
		if (taskDao.delete(task) > 0) {
			tasks.remove(select);
			clearUselessFile();
			showMessage("Remove Task Successfully!");
		} else
			showMessage("Remove Task Failed!");
		taskPanel.getTaskTableModel().setData(tasks);
		taskPanel.getFileTableModel().setData(null);
		taskPanel.init();
	}

	private void setTaskToPanle(int select) {
		// TODO Auto-generated method stub
		List<Task> tasks = getUser().getTasks();
		if (tasks == null)
			return;
		if (select >= tasks.size())
			return;
		Task task = tasks.get(select);
		taskPanel.getTaskNameField().setText(task.getTaskName());
		taskPanel.getDeadlineField().setText(task.getDeadline());
		taskPanel.getPriorityComboBox().setSelectedIndex(task.getPriority());
		taskPanel.getIntroductionArea().setText(task.getTaskIntroduction());
		showFiles(task);
	}

	public void showFiles(Task task) {
		if (task == null)
			return;
		List<File> files = task.getFiles();
		if (files == null)
			return;
		taskPanel.getFileTableModel().setData(files);
	}

	private void showMessage(String message) {
		JOptionPane.showMessageDialog(null, message);
	}

	private void taskTableIsChosen() {
		// TODO Auto-generated method stub
		int select = taskPanel.getTaskTable().getSelectedRow();
		if (select == -1)
			return;
		setTaskToPanle(select);
		Task task = getUser().getTasks().get(select);
		if (!task.hasLoadFiles())
			loadTask(task);
		showFiles(task);
		// set component enabled
		taskPanel.getRemoveTaskButton().setEnabled(true);
		taskPanel.getModifyButton().setEnabled(true);
		taskPanel.getAddFileButton().setEnabled(true);
		taskPanel.getDelFileButton().setEnabled(false);

	}

	public void valueChanged(ListSelectionEvent event) {
		// TODO Auto-generated method stub
		if (event.getSource() == taskPanel.getTaskTable().getSelectionModel()) {
			taskTableIsChosen();
		}
		if (event.getSource() == taskPanel.getFilesTable().getSelectionModel()) {
			fielTableIsChosen();
		}
	}
}
